package interaction;

import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.behaviors.PickMouseBehavior;
import java.awt.AWTEvent;
import java.awt.event.MouseEvent;
import java.util.*;
import javax.media.j3d.*;

import objects.Clock;

import start.Config;

/**
 * This class implements a simple pick behaviour. It prints out a message
 * identifying which object has been picked by using the userData of the object.
 * The use of this class is demonstrated in SimplePick.
 *
 * @author I.J.Palmer
 * @author Dennis Wittkoetter
 * @version 1.0
 */
public class Pick extends PickMouseBehavior {
    private Object pickObj;
    
    /**
     * The wake up criteria. This is set to trigger on mouse events using the
     * MOUSE_EVENT_MASK.
     */
    WakeupOnAWTEvent buttonPressed = new WakeupOnAWTEvent(MouseEvent.MOUSE_EVENT_MASK);

    /**
     * @param pickRoot BranchGroup that is the root of the picking operation.
     * @param pickCanvas Canvas3D used in the pick operation.
     * @param pickBounds Bounds that define the behaviour's active region.
     */
    public Pick(Canvas3D pickCanvas, BranchGroup pickRoot, Object pickObj, Bounds pickBounds) {
        super(pickCanvas, pickRoot, pickBounds);
        setSchedulingBounds(pickBounds);
        this.pickObj = pickObj;
    }

    /**
     * Sets the wake up criterion to the mouse button criteria
     */
    public void initialize() {
        wakeupOn(buttonPressed);
    }

    /**
     * Where the processing is carried out. This obtains the AWT mouse event,
     * checks if it is the left mouse button and then uses the x and y
     * coodinates of the mouse position to pick an object. A message is printed
     * according to which object has been picked. Finally the wake up condition
     * is set to the mouse criterion again.
     */
    @SuppressWarnings("rawtypes")
	@Override
    public void processStimulus(Enumeration criteria) {
        WakeupOnAWTEvent theCriterion = (WakeupOnAWTEvent) criteria.nextElement();
        AWTEvent theEvents[] = theCriterion.getAWTEvent();
        if (theEvents[0].getID() == MouseEvent.MOUSE_RELEASED) {
            MouseEvent theMouseEvent = (MouseEvent) theEvents[0];
            if ((theMouseEvent.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
                int xpos = theMouseEvent.getX();
                int ypos = theMouseEvent.getY();
                
                Shape3D pickedShape = null;		//kein Primitive! Wir brauchen die Shapes.
                PickResult pickResult = null;
                pickCanvas.setShapeLocation(xpos, ypos);
                pickResult = pickCanvas.pickClosest();
                
                if (pickResult != null) {	//irgendwas erwischt
                	pickedShape = (Shape3D) pickResult.getNode(PickResult.SHAPE3D);	//auch hier: Shape3D statt Primitive
                	if (Config.debug)	// Debug: Wurde ueberhaupt irgendwas erwischt?
                		System.out.println("Treffer");
                	
                	if (pickedShape != null) {		//Shape gespickt
                		String pickStr = (String) pickedShape.getUserData();	//UserData lesen
                		if (pickStr != null) {   	//nur wenn UserData gesetzt wurden                    	
	                		System.out.println("Gepickt: " + pickStr);
	                		animateClock(pickStr);	//Animation starten bei korrekten UserData
                		}
                	}
                } 
                else {	//voll daneben
                    System.out.println("Daneben");
                }
            }
        }
        wakeupOn(buttonPressed);
    }
    
    /**
     * This performs no processing but is required as the parent class is
     * abstract.
     */
    @Override
    public void updateScene(int xpos, int ypos) {}
    
    /**
     * Startet die Uhr, falls das passende Objekt gepickt wurde.
     * @see Clock
     */
    private void animateClock(String str) {
    	if (str == null)
    		return;		//Abbruch
        	
    	if (pickObj instanceof Clock) {
    		Clock clock = (Clock)pickObj;
    		    		
    		if ((str.compareTo("Pendel") == 0)
    		||  (str.compareTo("Woelbung") == 0)
    		||  (str.compareTo("Koerper") == 0)
    		||  (str.contains("Ring_innen"))
    		||  (str.contains("Pendelstange"))) {
    			if (!clock.isRunning()) 
    				clock.start();
    			else
    				clock.stop();
    		}
    	}
    }
}